package ui.window;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;

import org.apache.pivot.beans.BXML;
import org.apache.pivot.beans.Bindable;
import org.apache.pivot.collections.Map;
import org.apache.pivot.collections.Sequence;
import org.apache.pivot.serialization.SerializationException;
import org.apache.pivot.util.Resources;
import org.apache.pivot.wtk.Alert;
import org.apache.pivot.wtk.Border;
import org.apache.pivot.wtk.FileBrowserSheet;
import org.apache.pivot.wtk.Frame;
import org.apache.pivot.wtk.ImageView;
import org.apache.pivot.wtk.MessageType;
import org.apache.pivot.wtk.Orientation;
import org.apache.pivot.wtk.Prompt;
import org.apache.pivot.wtk.ScrollPane;
import org.apache.pivot.wtk.Sheet;
import org.apache.pivot.wtk.SheetCloseListener;
import org.apache.pivot.wtk.TabPane;
import org.apache.pivot.wtk.ScrollPane.ScrollBarPolicy;
import org.apache.pivot.wtk.TablePane;
import org.apache.pivot.wtk.TextArea;
import org.apache.pivot.wtk.content.ButtonData;
import org.apache.pivot.wtk.media.Image;

import ui.extra.Ruler;
import ui.listeners.EditorDragDropFileListener;
import ui.listeners.ImportDragDropFileListener;
import ui.listeners.MDKTabPaneListener;
import ui.listeners.MenuBarListener;
import ui.listeners.ToolbarListener;
import ui.other.TabData;

public class MDKWindow extends Frame implements Bindable{

	/**
	 * Le Listener a l'ecoute de la barre de menus 
	 */
	@SuppressWarnings("unused")
	private MenuBarListener menuBarListener;
	
	/**
	 * Le Listener a l'ecoute du gestionnaire d'onglets 
	 */
	private MDKTabPaneListener tabPaneListener;
	
	@SuppressWarnings("unused")
	private EditorDragDropFileListener editorDragDropListener;
	@SuppressWarnings("unused")
	private ImportDragDropFileListener importDragDropListener;
	
	@SuppressWarnings("unused")
	private ToolbarListener toolBarListener;
	
	@BXML private TabPane tabPane;
	@BXML private TablePane mainContainer;
	@BXML private TablePane.Row toolbarRow;
	@BXML private TablePane.Row converserRow;
	@BXML private TablePane.Row editorRow;
	@BXML private TablePane.Row terminalRow;
	
	@BXML private ImageView importPicture;
	@BXML private ImageView exportPicture;
	
	private Image musicIco;
		
	public MDKWindow(){
		menuBarListener = new MenuBarListener(this);
		toolBarListener = new ToolbarListener(this);
	}
	
	public void initialize(Map<String, Object> namespace, URL location, Resources arg2) {
		editorDragDropListener = new EditorDragDropFileListener(this, tabPane);
		importDragDropListener = new ImportDragDropFileListener(this, importPicture);

		ButtonData dat = (ButtonData) TabPane.getTabData(tabPane.getSelectedTab());
		musicIco = dat.getIcon();
		
		tabPaneListener = new MDKTabPaneListener(this, (Prompt)namespace.get("confirmCloseTabPrompt"));

		tabPane.getTabPaneListeners().add(tabPaneListener);
	}
	
	public void newFile(){
		addTab("New file*", null);
		tabPane.setSelectedIndex(tabPane.getTabs().getLength() - 1);
	}
	
	/**
	 * Methode permettant de charger un fichier
	 * @param fichier
	 */
	public void loadFile(File fichier){
	
		if(!this.isNewFile())
		{
			this.addTab(fichier.getName(), new TabData(fichier.getAbsolutePath()));
			tabPane.setSelectedIndex(tabPane.getTabs().getLength()-1);
		}
		
		Border b = (Border) tabPane.getSelectedTab();
		Border b2 = (Border) b.get(0);
		ScrollPane scro = (ScrollPane) b2.get(0);
		TextArea txt = (TextArea) scro.get(0);
		try {
			txt.setText(new FileReader(fichier));
			
			ButtonData dat = (ButtonData) TabPane.getTabData(tabPane.getSelectedTab());
			dat.setText(fichier.getName());
			dat.setUserData(new TabData(fichier.getAbsolutePath()));

			tabPane.validate();
			
		} catch (Exception e) {
			Alert.alert(MessageType.ERROR, "Une erreur est survenue lors du chargement du fichier : " + fichier.getName(), this);
		}
	}
	
	/**
	 * Methode permettant d'enregistrer un fichier
	 * @param fichier
	 */
	public void saveFile(){
		if(!this.isNewFile())
		{
			try {
				Border b = (Border) tabPane.getSelectedTab();
				Border b2 = (Border) b.get(0);
				ScrollPane scro = (ScrollPane) b2.get(0);
				TextArea txt = (TextArea) scro.get(0);
				
				ButtonData dat = (ButtonData) TabPane.getTabData(tabPane.getSelectedTab());
				TabData tabData = (TabData) dat.getUserData();
				
				BufferedWriter buffer = new BufferedWriter(new FileWriter(new File(tabData.getPathToFile())));
				buffer.write(txt.getText());
				buffer.close();
				
				tabPane.validate();
			} catch (IOException e1) {
				Alert.alert(MessageType.ERROR, "Erreur lors de la sauvegarde du fichier", this);
			}
		}
		else
		{
			FileBrowserSheet.Mode fileBrowserSheetMode = FileBrowserSheet.Mode.valueOf("SAVE_AS");
        	final FileBrowserSheet fileBrowserSheet = new FileBrowserSheet();

        	fileBrowserSheet.setMode(fileBrowserSheetMode);
        	fileBrowserSheet.open(this, new SheetCloseListener() {
				public void sheetClosed(Sheet sheet) {
        			if (sheet.getResult()) {
        				Sequence<File> selectedFiles = fileBrowserSheet.getSelectedFiles();
        				saveFileAs(selectedFiles.get(0));
        			}
        		}
        	});
		}
	}
	
	
	/**
	 * Methode permettant d'enregistrer un fichier
	 * @param fichier
	 */
	public void saveFileAs(File fichier){
		Border b = (Border) tabPane.getSelectedTab();
		Border b2 = (Border) b.get(0);
		ScrollPane scro = (ScrollPane) b2.get(0);
		TextArea txt = (TextArea) scro.get(0);
		

		try {
			BufferedWriter buffer = new BufferedWriter(new FileWriter(fichier));
			buffer.write(txt.getText());
			buffer.close();
			
			ButtonData dat = (ButtonData) TabPane.getTabData(tabPane.getSelectedTab());
			dat.setText(fichier.getName());
			dat.setUserData(new TabData(fichier.getAbsolutePath()));
			
			tabPane.validate();
			
		} catch (IOException e1) {
			Alert.alert(MessageType.ERROR, "Impossible de creer le fichier : " + fichier.getName(), this);
		}
	}
	
	/**
	 * Methode permettant d'ajouter un nouvel onglet a notre fenetre
	 * @param tabName : nom de l'onglet
	 * @param tabData : certaines donnee comme le chemin absolu du fichier
	 */
	public void addTab(String tabName, TabData tabData){
		ScrollPane scroll = new ScrollPane();
		scroll.setHorizontalScrollBarPolicy(ScrollBarPolicy.FILL);
		scroll.setVerticalScrollBarPolicy(ScrollBarPolicy.FILL_TO_CAPACITY);
		
		Ruler ruler = new Ruler();
		ruler.setOrientation(Orientation.VERTICAL);
		
		TextArea txt = new TextArea();
		
		try {
			txt.setStyles("{font:'Courier New 12'}");
		} catch (SerializationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		scroll.setView(txt);
		scroll.setRowHeader(ruler);
		
		Border borderInside = new Border();
		borderInside.setContent(scroll);
		
		Border globalBorder = new Border();
		globalBorder.setContent(borderInside);
		
		tabPane.getTabs().add(globalBorder);

		ButtonData onglet = new ButtonData(musicIco, tabName);
		onglet.setUserData(tabData);
		
		TabPane.setTabData(globalBorder, onglet);
		tabPane.validate();
	}

	private Boolean isNewFile(){
		ButtonData dat = (ButtonData) TabPane.getTabData(tabPane.getSelectedTab());
		TabData tabData = (TabData) dat.getUserData();
		if(tabData != null)
		{
			return (tabData.getPathToFile() == null);
		}
		return true;
	}
	
	public void switchToConverser(){
		converserRow.setHeight(1, true);
		editorRow.setHeight(0, true);
		terminalRow.setHeight(0, true);

		mainContainer.validate();
	}
	
	public void switchToEditor(){
		converserRow.setHeight(0, true);
		editorRow.setHeight(1, true);
		terminalRow.setHeight(0, true);
		
		tabPane.validate();
	}
	
	public void switchToConsole(){
		converserRow.setHeight(0, true);
		editorRow.setHeight(0, true);
		terminalRow.setHeight(1, true);

		mainContainer.validate();
	}
}
